package com.bluesky.admin.controller.common;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.bluesky.common.config.AppConfig;
import com.bluesky.common.exception.CustomException;
import com.bluesky.common.result.R;
import com.bluesky.common.result.ResultCode;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Objects;


/**
 * <p>
 * 通用common 前端控制器
 * </p>
 *
 * @author Kevin
 */
@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {

    /**
     * 默认大小 50M
     */
    private static long DEFAULT_FILE_MAX_SIZE = 50 * 1024 * 1024;

    /**
     * 下载文件名重新编码
     *
     * @param response     响应对象
     * @param realFileName 真实文件名
     * @return
     */
    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {
        String percentEncodedFileName = percentEncode(realFileName);
        StringBuilder contentDispositionValue = new StringBuilder();
        contentDispositionValue.append("attachment; filename=")
                .append(percentEncodedFileName)
                .append(";")
                .append("filename*=")
                .append("utf-8''")
                .append(percentEncodedFileName);

        response.setHeader("Content-disposition", contentDispositionValue.toString());
    }

    /**
     * 百分号编码工具方法
     *
     * @param s 需要百分号编码的字符串
     * @return 百分号编码后的字符串
     */
    public static String percentEncode(String s) throws UnsupportedEncodingException {
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
        return encode.replaceAll("\\+", "%20");
    }

    @PostMapping("/upload")
    @SneakyThrows
    public R upload(MultipartFile file, HttpServletRequest request) {
        String biz = request.getParameter("biz");
        if (StrUtil.isBlank(biz)) {
            throw new CustomException(ResultCode.PARAM_MISS.getMessage());
        }
        if (Objects.isNull(file)) {
            throw new CustomException(ResultCode.PARAM_MISS.getMessage());
        }
        if (file.getSize() > DEFAULT_FILE_MAX_SIZE) {
            throw new CustomException(String.format("文件超过最大限制，最大%sM", DEFAULT_FILE_MAX_SIZE / 1024 / 1024));
        }
        String mainName = FileUtil.mainName(file.getOriginalFilename());
        String extName = FileUtil.extName(file.getOriginalFilename());
        if (StrUtil.isBlank(extName)) {
            extName = FileTypeUtil.getType(file.getInputStream());
        }
        String filename = mainName + "_" + System.nanoTime() + "." + extName;
        String filepath = "/" + biz + "/" + filename;
        file.transferTo(FileUtil.touch(AppConfig.getProfile() + filepath));

        JSONObject json = new JSONObject();
        json.put("filepath", filepath);
        json.put("url", AppConfig.getServerUrl() + "/common/download?biz=" + biz + "&filepath=" + filepath);
        return R.success(json);
    }

    @GetMapping("/download")
    @SneakyThrows
    public void download(@RequestParam String filepath, HttpServletResponse response) {
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        setAttachmentResponseHeader(response, FileUtil.getName(filepath));
        FileUtil.writeToStream(AppConfig.getProfile() + filepath, response.getOutputStream());
    }

}
